import React, {PropsWithChildren, useCallback, useEffect, useMemo, useState} from 'react'
import {Button, Cell, CellGroup, SafeArea, SearchBar, Space} from "@nutui/nutui-react-taro";
import Taro, {useLoad} from "@tarojs/taro";
import styles from "./marketOrderDetail.module.sass"
import {
    addMarketOrderItemFromBarcode,
    addMarketOrderItemsFromSubGoodsKeyList,
    convertToDeliveryOrder, deleteMarketOrder,
    deleteMarketOrderItem,
    deleteMarketOrderItemSubGoods,
    getMarketOrderDetail,
    MarketOrderItem,
    submitMarketOrder,
    updateMarketOrderItemAmount, updateMarketOrderItemNote, updateMarketOrderItemSubAmount, updateMarketOrderItemSubNote
} from "../apis/MarketOrderApi";
import {OffsetDateTime} from "@js-joda/core";
import {DATE_WITH_HOUR_MINUTE_FORMATER, DATE_WITH_TIME_FORMATER,} from "../utils/Date";
import {Add, ArrowRight, Top,} from "@nutui/icons-react-taro";
import employeeStore from "../store/EmployeeStore";
import OrderListItem from "../components/OrderListItem";
import {ScrollView, View} from "@tarojs/components";
import ScanBarcodeButton from "../components/ScanBarcodeButton";
import SelectGoodsPopup from "../components/SelectGoodsPopup";
import ArrayUtils from "@zxy-cn/array-utils"
import {ExcelColumn, exportToWorkbook, saveAndOpenWorkbook} from "../utils/ExcelUtils";
import ExportToExcelConfigurationDialog from "../components/ExportToExcelConfigurationDialog";
import {barcodeRepeated, scanSuccess} from "../utils/ScanCodeUtils";
import MyNavigationBar, {useMyNavigationBarHeight} from "../components/MyNavigationBar";
import marketOrderInMarketPageStackStore from "../store/MarketOrderInMarketPageStackStore";
import {observer} from "mobx-react";

export interface MarketOrderDetailProps extends PropsWithChildren {

}

const columns: ExcelColumn<MarketOrderItem>[] = [
    {
        key: "barcode",
        header: "条码",
    }, {
        key: "subGoodsNumber",
        header: "子商品编码",
        renderToString: item => item.subGoods?.number ?? ""
    }, {
        key: "subGoodsName",
        header: "子商品名称",
        renderToString: item => item.subGoods?.name ?? ""
    },
    {
        key: "name",
        header: "名称",
    }, {
        key: "amountInOrder",
        header: "数量",
        renderToString: item => {
            return `${item.amountInOrder}${item.unit?.name ?? ""}`
        }
    },
    {key: "note", header: "备注",},
    {
        key: "boxSpecification",
        header: "箱规",
    },];

const MARKET_ORDER_ITEMS_EXPORT_COLUMNS_KEY = "MARKET_ORDER_ITEMS_EXPORT_COLUMNS"

const MarketOrderDetail: React.FC<MarketOrderDetailProps> = ({}) => {
    const [title, setTitle] = useState("卖场订单详情")
    const [marketOrderId, setMarketOrderId] = useState<number>()
    const data = marketOrderInMarketPageStackStore.detail
    useLoad((params) => {
        setMarketOrderId(params.id)
    })
    useEffect(() => {
        if (marketOrderId) {
            Taro.showLoading()
            getMarketOrderDetail(marketOrderId)
                .then(response => {
                    marketOrderInMarketPageStackStore.setDetail(response.data)
                    setTitle(response.data.market.name + "订单明细")
                }).finally(() => {
                Taro.hideLoading()
            });
        }
    }, [marketOrderId]);

    const canDelete = useMemo(() => {
        return employeeStore.hasAuthority("卖场_订单_删除") && data && !data.submitDateTime
    }, [employeeStore.employee, data]);

    const canSubmit = useMemo(() => {
        return employeeStore.hasAuthority("卖场_订单_下单") && !!data && !data.submitDateTime
    }, [employeeStore.employee, data]);

    const canAudit = useMemo(() => {
        return employeeStore.hasAuthority("卖场_订单_转化为送货单") && !!data && !data.deliveryDateTime && !!data.submitDateTime
    }, [employeeStore.employee, data]);

    const canEdit = useMemo(() => {
        return employeeStore.hasAuthority("卖场_订单_添加货品") && (canAudit || canSubmit)
    }, [canSubmit, canAudit, employeeStore.employee]);


    const [selectGoodsPopupVisible, setSelectGoodsPopupVisible] = useState(false)

    const [exportToExcelDialogVisible, setExportToExcelDialogVisible] = useState(false)

    const scrollToBottom = useCallback(()=> {
        setScrollTop((data?.items?.length??0) * 200)
    },[data])


    const [deleting, setDeleting] = useState(false)
    const [scrollToTargetKeyword, setScrollToTargetKeyword] = useState<string>()
    let scrollToTargetId = useMemo(() => {
        if (!!data?.items && !!scrollToTargetKeyword) {
            let item = data.items.find(it => {
                const keyword = scrollToTargetKeyword.toLowerCase()
                return it.name.toLowerCase().includes(keyword)
                    || it.barcode.toLowerCase().includes(keyword)
                    || it.subGoods?.number.toLowerCase().includes(keyword)
                    || it.subGoods?.name.toLowerCase().includes(keyword)
                || [it.id,it.subGoods?.id].filter(it=>!!it).join("-")===keyword
            });

            if (!!item) {
                let id = "item" + [item.id, item.subGoods?.id].filter(it => !!it).join("-");
                return id
            }
        }
        return undefined
    }, [scrollToTargetKeyword, data?.items]);
    let navigationBarHeight = useMyNavigationBarHeight();
    const [scrollTop,setScrollTop] = useState(0)
    return <>
        <MyNavigationBar>{title}</MyNavigationBar>
        {data && <>
            <SearchBar style={{position: "static", top: 0, zIndex: 999}} onChange={setScrollToTargetKeyword}
                       placeholder={"搜索并跳转到指定货品"}/>
            <ScrollView style={{height: `calc(100vh - ${navigationBarHeight}px - 44px)`}} scrollY
                        scrollTop={scrollTop}
                        scrollIntoView={scrollToTargetId}>

                <View style={{position: "relative"}}>
                    <CellGroup divider={false}>
                        <Cell>{data.createdBy.name}创建于{data.createdDateTime.format(DATE_WITH_HOUR_MINUTE_FORMATER)}</Cell>
                        {data.submitDateTime && <Cell title={"提交时间"}
                                                      extra={(data.submitDateTime).format(DATE_WITH_HOUR_MINUTE_FORMATER)}></Cell>}
                        {data.deliveryDateTime && <Cell title={"已出货"} extra={<ArrowRight/>} onClick={() => {
                            // TODO Taro.navigateTo
                        }}></Cell>}
                        {(canDelete || canSubmit || canAudit) &&
                            <Cell extra={
                                <Space>
                                    <Button onClick={async () => {
                                        setExportToExcelDialogVisible(true)
                                    }}>导出</Button>
                                    <ExportToExcelConfigurationDialog
                                        visible={exportToExcelDialogVisible}
                                        rememberedColumnsStorageKey={MARKET_ORDER_ITEMS_EXPORT_COLUMNS_KEY}
                                        selectableColumns={columns}
                                        onCancel={() => {
                                            setExportToExcelDialogVisible(false)
                                        }}
                                        onConfirm={async values => {
                                            let workbook = exportToWorkbook(data.items, columns.filter(it => values.includes(it.key)));
                                            await saveAndOpenWorkbook(workbook, `${data.market.name}${(data.createdDateTime).format(DATE_WITH_TIME_FORMATER)}`)
                                            setExportToExcelDialogVisible(false)
                                        }}/>
                                    {canDelete &&
                                        <Button type={"danger"} fill={"outline"} loading={deleting}
                                                onClick={async () => {
                                                    setDeleting(true)
                                                    try {
                                                        await deleteMarketOrder(data.id)
                                                        marketOrderInMarketPageStackStore.removeItemByKey(data.id)
                                                        await Taro.navigateBack()
                                                    } finally {
                                                        setDeleting(false)
                                                    }
                                                }}>删除</Button>}
                                    {canSubmit && <Button type={"primary"}
                                                          onClick={() => {
                                                              Taro.showModal({
                                                                  title: "确定要提交吗",
                                                                  content: "提交后你将无法再修改"
                                                              }).then(result => {
                                                                  if (result.confirm)
                                                                      submitMarketOrder(marketOrderId!!).then(() => {
                                                                          marketOrderInMarketPageStackStore.updateDetail({
                                                                              ...data,
                                                                              submitDateTime: OffsetDateTime.now()
                                                                          })
                                                                      })
                                                              })
                                                          }}>提交</Button>}
                                    {canAudit && <Button type={"primary"}
                                                         onClick={() => {
                                                             Taro.showModal({
                                                                 title: "确定要审核订单吗",
                                                                 content: "审核后你将无法再修改，且生成送货单"
                                                             }).then(result => {
                                                                 if (result.confirm)
                                                                     convertToDeliveryOrder(marketOrderId!!).then(() => {
                                                                         marketOrderInMarketPageStackStore.updateDetail({
                                                                             ...data,
                                                                             deliveryDateTime: OffsetDateTime.now(),
                                                                         })
                                                                     })
                                                             })
                                                         }}>审核</Button>}

                                </Space>
                            }/>}
                    </CellGroup>

                    {data.items.map((item, index) => {
                        let id = "item" + [item.id, item.subGoods?.id].filter(it => !!it).join("-");
                        return <OrderListItem id={id} key={id} data={item}
                                       canEdit={canEdit}
                                       onClick={() => {
                                           Taro.navigateTo({url: `/pages/goodsDetail?id=${item.id}`})
                                       }}
                                       onDelete={async () => {
                                           if (!item.subGoods) {
                                               await deleteMarketOrderItem(marketOrderId!!, item.id)
                                           } else {
                                               await deleteMarketOrderItemSubGoods(marketOrderId!!, item.id, item.subGoods.id)
                                           }
                                           ArrayUtils.remove(data!.items, item)
                                           marketOrderInMarketPageStackStore.updateDetail({
                                               ...data,
                                               items: Array.from(data?.items),
                                           })
                                       }}
                                       onUpdateAmount={async (value, unitId) => {
                                           if (!item.subGoods) {
                                               await updateMarketOrderItemAmount(marketOrderId!!, item.id, {
                                                   unitId,
                                                   amount: value
                                               });
                                           } else {
                                               await updateMarketOrderItemSubAmount(marketOrderId!!, item.id, {
                                                   unitId,
                                                   amount: value
                                               }, item.subGoods.id);
                                           }
                                           Taro.showToast({
                                               title: "修改数量成功！",
                                               icon: "success",
                                           })
                                           let items = Array.from(data!.items);
                                           items[index] = {
                                               ...items[index],
                                               amountInOrder: value,
                                               unit: items[index].units.find(it => it.id === unitId)
                                           }
                                           marketOrderInMarketPageStackStore.updateDetail({
                                               ...data,
                                               items: items
                                           })
                                       }}
                                       onUpdateNote={async (note) => {
                                           if (!item.subGoods) {
                                               await updateMarketOrderItemNote(marketOrderId!!, item.id, note)
                                           } else {
                                               await updateMarketOrderItemSubNote(marketOrderId!!, item.id, note, item.subGoods.id)
                                           }
                                           let items = Array.from(data!.items);
                                           items[index].note = note
                                           marketOrderInMarketPageStackStore.updateDetail({
                                               ...data,
                                               items: items
                                           })
                                       }}
                        />
                    })}</View>
                <View id={"bottomTest"}></View>
                <SafeArea position={"bottom"}/>
            </ScrollView>

            {!!data && <View className={styles.bottomBar}>
                <Space className={styles.bottomSpace}>
                    <Button fill={"outline"} icon={<Top/>} onClick={() => {
                        Taro.pageScrollTo({
                            scrollTop: 0,
                            duration: 300,
                        })
                    }}>回到顶部</Button>
                    {canEdit && <Button icon={<Add/>} type={"primary"} onClick={() => {
                        setSelectGoodsPopupVisible(true)
                    }}>添加{`(${data.items.length})`}</Button>}
                    {canEdit && <ScanBarcodeButton onScanSuccess={async (barcode, continueScan) => {
                        if (data.items.map(it => it.barcode).includes(barcode)) {
                            await barcodeRepeated(`订单中已存在此货品\t${barcode}`)

                            setTimeout(() => {
                                continueScan()
                            }, 100)
                            return
                        }
                        let response = await addMarketOrderItemFromBarcode(marketOrderId!!, barcode);
                        let item = response.data
                        let array = Array.from(data.items)
                        array.push({...item, id: item.goodsId})
                        marketOrderInMarketPageStackStore.updateDetail({...data, items: array})
                        await scanSuccess()
                        scrollToBottom()
                        // setTimeout(() => {
                        //     continueScan()
                        // }, 100)
                    }}>扫码</ScanBarcodeButton>}
                </Space>
                <SafeArea position={"bottom"}/>
            </View>}
        </>}
        <SelectGoodsPopup visible={selectGoodsPopupVisible} onClose={() => setSelectGoodsPopupVisible(false)}
                          existedGoodsList={data?.items}
                          editMarketOrderId={marketOrderId} onConfirm={async value => {
            const response = (await addMarketOrderItemsFromSubGoodsKeyList(marketOrderId!, value))
            let array = Array.from(data?.items ?? [])
            marketOrderInMarketPageStackStore.updateDetail({
                ...data!,
                items: array.concat(response.data.map(item => ({...item, id: item.goodsId, subGoods: item.subGoods})))
            })
            setTimeout(() => {
                scrollToBottom()
            }, 300)
        }}/>
    </>
}

export default observer(MarketOrderDetail)
